package com.ansion.utils.dark.setting;

import android.annotation.SuppressLint;
import android.content.res.Configuration;
import android.os.Build;

import androidx.appcompat.app.AppCompatDelegate;

import com.ansion.log.VLog;
import com.ansion.preference.TurboPreferenceUtils;
import com.ansion.utils.ResourceUtils;

import java.util.ArrayList;

/**
 * @user: dong.wang
 * @data: 2020/10/26 7:38 PM
 * @desc: Dark Mode 切换工具
 */
public class DarkSetting {
    private final String TAG = "DarkSetting";

    //当前系统主题的内存变量
    private static int currentSystemTheme = -1;
    //当前app主题的内存变量
    private static int currentAppTheme = -1;

    private static final String THEME_DARK_STATUS = "dark_status";
    private static final ArrayList<Integer> THEME_STATUS = new ArrayList<Integer>() {
    };

    private DarkSetting() {
        THEME_STATUS.clear();
        THEME_STATUS.add(AppCompatDelegate.MODE_NIGHT_NO);
        THEME_STATUS.add(AppCompatDelegate.MODE_NIGHT_YES);

        if (sdkBiggerThanP()) {
            THEME_STATUS.add(0, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
        }
    }

    public static DarkSetting getInstance() {
        return SingletonHolder.setting;
    }

    private static class SingletonHolder {
        private static DarkSetting setting = new DarkSetting();
    }

    public static boolean sdkBiggerThanP() {
        return Build.VERSION.SDK_INT > Build.VERSION_CODES.P;
    }

    /**
     * 主动设置dark，不包括跟随系统时系统设置dark
     *
     * @return
     */
    public static boolean isDarkMode() {
        return currentAppTheme == AppCompatDelegate.MODE_NIGHT_YES;
    }

    /**
     * 跟随系统
     *
     * @return
     */
    public static boolean isFollowSystem() {
        return currentAppTheme == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
    }

    /**
     * 当前是否是dark，跟随系统时系统是dark或者主动设置dark
     *
     * @return
     */
    public static boolean isCurrentDarkMode() {
        return isFollowSystem() && DarkSetting.getInstance().getCurrentSystemTheme() == AppCompatDelegate.MODE_NIGHT_YES || isDarkMode();
    }

    /**
     * 返回值 实际为 THEME_STATUS 的下标
     *
     * @return
     */
    public int getAppThemeSettingStatus() {
        int status = TurboPreferenceUtils.getInstance().getInt(THEME_DARK_STATUS, -1);
        if (status == -1) {
            return 0;
        }
        return status;
    }

    /**
     * status 实际为 THEME_STATUS 的下标
     */
    @SuppressLint("WrongConstant")
    public boolean setAppThemeSettingStatus(int status) {
        int theme = THEME_STATUS.get(status);
        int themResult = theme;
        VLog.i(TAG, "setAppThemeSettingStatus status:%d,theme:%d,currentAppTheme:%d,currentSystemTheme:%d", status, theme, currentAppTheme, currentSystemTheme);
        if (theme == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) {//跟随系统
            if (currentAppTheme == currentSystemTheme) {//当前app主题与系统主题一致
                saveStatus(status);
                return false;
            }
            themResult = currentSystemTheme;
        } else {//不跟随系统
            if (THEME_STATUS.size() == 3) {
                if (theme == currentAppTheme) {//当前主题与要设置的主题一致
                    saveStatus(status);
                    return false;
                }
            }
        }
        AppCompatDelegate.setDefaultNightMode(themResult);
        saveStatus(status);
        ResourceUtils.resetContext();
        return true;
    }

    private void saveStatus(int status) {
        currentAppTheme = THEME_STATUS.get(status);
        TurboPreferenceUtils.getInstance().putInt(THEME_DARK_STATUS, status);
    }

    /**
     * 加载当前主题
     */
    public void applyCurrentTheme() {
        int sysMode = getCurrentSystemTheme();
        currentSystemTheme = sysMode;
        int status = getAppThemeSettingStatus();
        int mode = THEME_STATUS.get(status);
        if (mode == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) {
            AppCompatDelegate.setDefaultNightMode(sysMode);
            currentAppTheme = mode;
        } else {
            AppCompatDelegate.setDefaultNightMode(mode);
            currentAppTheme = mode;
        }

        ResourceUtils.resetContext();
    }

    /**
     * 获取当前的app主题
     */
    public int getCurrentAppTheme() {
        int status = getAppThemeSettingStatus();
        if (status != -1) {
            return THEME_STATUS.get(status);
        }

        return AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
    }

    /**
     * 获取应用的dark设置
     */
    public int getConfigurationUiMode() {
        int result = Configuration.UI_MODE_NIGHT_NO;
        if (getCurrentAppTheme() == AppCompatDelegate.MODE_NIGHT_YES) {
            result = Configuration.UI_MODE_NIGHT_YES;
        }
        return result;
    }

    /**
     * 监听系统uiMode变化，只监听BaseApplication中的onConfigurationChanged，其他的activity和fragment没必要重复监听，
     * 一旦重复监听在develop-msg分支会出现系统主题获取错误的问题
     *
     * @param configure
     * @return
     */
    @SuppressLint("WrongConstant")
    public boolean onConfigurationChanged(int configure) {
        VLog.i(TAG, "onConfigurationChanged configure:%d", configure);
        int targetConfigure;
        switch (configure) {
            case Configuration.UI_MODE_NIGHT_YES:
                targetConfigure = AppCompatDelegate.MODE_NIGHT_YES;
                break;
            case Configuration.UI_MODE_NIGHT_NO:
                targetConfigure = AppCompatDelegate.MODE_NIGHT_NO;
                break;
            default:
                return false;
        }
        VLog.i(TAG, "onConfigurationChanged configure:%d,targetConfigure:%d,currentSystemTheme:%d", configure, targetConfigure, currentSystemTheme);
        int currentAppThemeTemp = getCurrentAppTheme();
        if (currentAppThemeTemp != AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) {
            //虽然不是follow_system，但是当前系统的主题要同步变更
            currentSystemTheme = targetConfigure;
            VLog.i(TAG, "onConfigurationChanged is not FOLLOW_SYSTEM return");
            return false;
        }

        if (targetConfigure == currentSystemTheme) { //系统新主题与当前主题一致
            VLog.i(TAG, "onConfigurationChanged targetConfigure == currentSystemTheme return");
            return false;
        }

        currentSystemTheme = targetConfigure;
        AppCompatDelegate.setDefaultNightMode(targetConfigure);
        ResourceUtils.resetContext();
        return true;
    }

    /***
     * 获取当前系统主题。这个方法会在多次重复调用AppCompatDelegate.setDefaultNightMode后取到主题会出错。
     * 所以一定要控制好AppCompatDelegate.setDefaultNightMode的时机
     * @return
     */
    public int getCurrentSystemTheme() {
        //这个方法在app主题与系统不一致的时候取的是当前app的主题，所以要慎用
        int mode = AppCompatDelegate.MODE_NIGHT_NO;
        if ((ResourceUtils.getContext().getResources().getConfiguration().uiMode &
                Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES) {
            mode = AppCompatDelegate.MODE_NIGHT_YES;
        }
        return mode;
    }
}
